package com.jweb.framework.core.support;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;


public class AntPathMatcher implements PathMatcher {
	
	
	private static final Pattern a = Pattern.compile("\\{[^/]+?\\}");
	public static final String DEFAULT_PATH_SEPARATOR = "/";
	private String b;
	private Map c;
	
	private static class a implements Comparator {

		public int a(String s, String s1) {
			if (s == null && s1 == null)
				return 0;
			if (s == null)
				return 1;
			if (s1 == null)
				return -1;
			boolean flag = s.equals(a);
			boolean flag1 = s1.equals(a);
			if (flag && flag1)
				return 0;
			if (flag)
				return -1;
			if (flag1)
				return 1;
			int i = a(s);
			int j = a(s1);
			int k = StringUtils.countOccurrencesOf(s, "{");
			int l = StringUtils.countOccurrencesOf(s1, "{");
			int i1 = i + k;
			int j1 = j + l;
			if (i1 != j1)
				return i1 - j1;
			int k1 = b(s);
			int l1 = b(s1);
			if (k1 != l1)
				return l1 - k1;
			if (i < j)
				return -1;
			if (j < i)
				return 1;
			if (k < l)
				return -1;
			return l >= k ? 0 : 1;
		}

		private int a(String s) {
			if (s.endsWith(".*"))
				s = s.substring(0, s.length() - 2);
			return StringUtils.countOccurrencesOf(s, "*");
		}

		private int b(String s) {
			Matcher matcher = AntPathMatcher.a().matcher(s);
			return matcher.replaceAll("#").length();
		}

		public int compare(Object obj, Object obj1) {
			return a((String) obj, (String) obj1);
		}

		private final String a;

		private a(String s) {
			a = s;
		}

		a(String s, a a1) {
			this(s);
		}
	}

	public AntPathMatcher() {
		b = "/";
		c = new WeakHashMap();
	}

	public void setPathSeparator(String s) {
		b = s == null ? "/" : s;
	}

	public boolean isPattern(String s) {
		return s.indexOf('*') != -1 || s.indexOf('?') != -1;
	}

	public boolean match(String s, String s1) {
		return doMatch(s, s1, true, null);
	}

	public boolean matchStart(String s, String s1) {
		return doMatch(s, s1, false, null);
	}

	protected boolean doMatch(String s, String s1, boolean flag, Map map) {
		if (s1.startsWith(b) != s.startsWith(b))
			return false;
		String as[] = StringUtils.tokenizeToStringArray(s, b);
		String as1[] = StringUtils.tokenizeToStringArray(s1, b);
		int i = 0;
		int j = as.length - 1;
		int k = 0;
		int l;
		for (l = as1.length - 1; i <= j && k <= l; k++) {
			String s2 = as[i];
			if ("**".equals(s2))
				break;
			if (!a(s2, as1[k], map))
				return false;
			i++;
		}

		if (k > l) {
			if (i > j)
				return s.endsWith(b) ? s1.endsWith(b) : !s1.endsWith(b);
			if (!flag)
				return true;
			if (i == j && as[i].equals("*") && s1.endsWith(b))
				return true;
			for (int i1 = i; i1 <= j; i1++)
				if (!as[i1].equals("**"))
					return false;

			return true;
		}
		if (i > j)
			return false;
		if (!flag && "**".equals(as[i]))
			return true;
		for (; i <= j && k <= l; l--) {
			String s3 = as[j];
			if (s3.equals("**"))
				break;
			if (!a(s3, as1[l], map))
				return false;
			j--;
		}

		if (k > l) {
			for (int j1 = i; j1 <= j; j1++)
				if (!as[j1].equals("**"))
					return false;

			return true;
		}
		while (i != j && k <= l) {
			int k1 = -1;
			for (int i2 = i + 1; i2 <= j; i2++) {
				if (!as[i2].equals("**"))
					continue;
				k1 = i2;
				break;
			}

			if (k1 == i + 1) {
				i++;
			} else {
				int j2 = k1 - i - 1;
				int k2 = (l - k) + 1;
				int l2 = -1;
				label0: for (int i3 = 0; i3 <= k2 - j2; i3++) {
					for (int j3 = 0; j3 < j2; j3++) {
						String s4 = as[i + j3 + 1];
						String s5 = as1[k + i3 + j3];
						if (!a(s4, s5, map))
							continue label0;
					}

					l2 = k + i3;
					break;
				}

				if (l2 == -1)
					return false;
				i = k1;
				k = l2 + j2;
			}
		}
		for (int l1 = i; l1 <= j; l1++)
			if (!as[l1].equals("**"))
				return false;

		return true;
	}

	private boolean a(String s, String s1, Map map) {
		UtilA a1 = (UtilA) c.get(s);
		if (a1 == null) {
			a1 = new UtilA(s);
			c.put(s, a1);
		}
		return a1.a(s1, map);
	}

	public String extractPathWithinPattern(String s, String s1) {
		String as[] = StringUtils.tokenizeToStringArray(s, b);
		String as1[] = StringUtils.tokenizeToStringArray(s1, b);
		StringBuilder stringbuilder = new StringBuilder();
		int i = 0;
		for (int j = 0; j < as.length; j++) {
			String s2 = as[j];
			if ((s2.indexOf('*') > -1 || s2.indexOf('?') > -1)
					&& as1.length >= j + 1) {
				if (i > 0 || j == 0 && !s.startsWith(b))
					stringbuilder.append(b);
				stringbuilder.append(as1[j]);
				i++;
			}
		}

		for (int k = as.length; k < as1.length; k++) {
			if (i > 0 || k > 0)
				stringbuilder.append(b);
			stringbuilder.append(as1[k]);
		}

		return stringbuilder.toString();
	}

	public Map extractUriTemplateVariables(String s, String s1) {
		LinkedHashMap linkedhashmap = new LinkedHashMap();
		boolean flag = doMatch(s, s1, true, linkedhashmap);
		Assert.state(flag, (new StringBuilder("Pattern \"")).append(s).append(
				"\" is not a match for \"").append(s1).append("\"").toString());
		return linkedhashmap;
	}

	public String combine(String s, String s1) {
		if (!StringUtils.hasText(s) && !StringUtils.hasText(s1))
			return "";
		if (!StringUtils.hasText(s))
			return s1;
		if (!StringUtils.hasText(s1))
			return s;
		if (match(s, s1))
			return s1;
		if (s.endsWith("/*"))
			if (s1.startsWith("/"))
				return (new StringBuilder(String.valueOf(s.substring(0, s
						.length() - 1)))).append(s1.substring(1)).toString();
			else
				return (new StringBuilder(String.valueOf(s.substring(0, s
						.length() - 1)))).append(s1).toString();
		if (s.endsWith("/**"))
			if (s1.startsWith("/"))
				return (new StringBuilder(String.valueOf(s))).append(s1)
						.toString();
			else
				return (new StringBuilder(String.valueOf(s))).append("/")
						.append(s1).toString();
		int i = s.indexOf('.');
		if (i == -1)
			if (s.endsWith("/") || s1.startsWith("/"))
				return (new StringBuilder(String.valueOf(s))).append(s1)
						.toString();
			else
				return (new StringBuilder(String.valueOf(s))).append("/")
						.append(s1).toString();
		String s2 = s.substring(0, i);
		String s3 = s.substring(i);
		int j = s1.indexOf('.');
		String s4;
		String s5;
		if (j != -1) {
			s4 = s1.substring(0, j);
			s5 = s1.substring(j);
		} else {
			s4 = s1;
			s5 = "";
		}
		String s6 = s2.endsWith("*") ? s4 : s2;
		String s7 = s3.startsWith("*") ? s5 : s3;
		return (new StringBuilder(String.valueOf(s6))).append(s7).toString();
	}

	public Comparator getPatternComparator(String s) {
		return new a(s, null);
	}

	static Pattern a() {
		return a;
	}

}
